﻿
//地址分配类
namespace n_AddressList
{
using System;
using n_ET;
using n_VdataList;
using n_VarList;
using n_VarType;
using n_FunctionList;

public static class AddressList
{
	public static bool MemoryError;
	
	//重置地址分配表
	public static void Reset()
	{
		MemoryError = false;
		
		Address = new bool[ VdataList.length ][];
		Number = new int[ VdataList.length ];
		StaticMaxAddr = new int[ VdataList.length ];
		MaxUsedAddressList = new int[ VdataList.length ][];
		UsedAddressList = new string[ VdataList.length ][];
		
		for( int i = 0; i < Address.Length; ++i ) {
			if( VdataList.Get( i ).AutoAllot ) {
				Number[ i ] = 0;
				StaticMaxAddr[ i ] = VdataList.Get( i ).StartAddress - 1;
				Address[ i ] = new bool[ VdataList.Get( i ).EndAddress - VdataList.Get( i ).StartAddress + 1 + 1000 ]; //这里防护分配溢出
			}
			//初始化最大使用地址列表
			MaxUsedAddressList[ i ] = new int[ FunctionList.length ];
			for( int j = 0; j < MaxUsedAddressList[ i ].Length; ++j ) {
				MaxUsedAddressList[ i ][ j ] = -1;
			}
			//初始化已用地址列表
			UsedAddressList[ i ] = new string[ FunctionList.length ];
			for( int j = 0; j < UsedAddressList[ i ].Length; ++j ) {
				UsedAddressList[ i ][ j ] = "";
			}
		}
	}
	
	//清除已分配地址
	public static void Clear()
	{
		for( int i = 0; i < Address.Length; ++i ) {
			if( VdataList.Get( i ).AutoAllot ) {
				for( int j = 0; j < Address[ i ].Length; ++j ) {
					Address[ i ][ j ] = false;
				}
			}
		}
	}
	
	//申请一种类型的空间
	public static int ApplyVarAddress( string Type )
	{
		string VdataName = VarType.GetStoreType( Type );
		int VdataIndex = VdataList.GetIndex( VdataName );
		if( VdataIndex == -1 ) {
			ET.WriteParseError( 0, "在申请变量存储空间时发现未定义的虚拟数据类型:" + VdataName );
			return -1;
		}
		if( !VdataList.Get( VdataIndex ).AutoAllot ) {
			return -1;
		}
		int Width = VarType.GetSize( Type );
		
		/*
		int of = 1;
		if( VdataIndex == 0 ) {
			of = 4;
		}
		*/
		
		for( int i = 0; i < Address[ VdataIndex ].Length; i += 1 ) {
			bool isOK = true;
			for( int j = 0; j < Width; ++j ) {
				if( i + j >= Address[ VdataIndex ].Length ) {
					
					//这个提示可能重复了
					MemoryError = true;
					ET.WriteLineError( 0, 0, "此类型存储区的分配空间已经不足: " + VdataName );
					return -1;
				}
				if( Address[ VdataIndex ][ i + j ] ) {
					isOK = false;
				}
			}
			if( isOK ) {
				for( int j = 0; j < Width; ++j ) {
					Address[ VdataIndex ][ i + j ] = true;
					if( i + j >= Number[ VdataIndex ] ) {
						Number[ VdataIndex ] = i + j + 1;
					}
				}
				return i + VdataList.Get( VdataIndex ).StartAddress;
			}
		}
		return -1;
	}
	
	//释放一个变量的地址
	public static void RemoveVar( int VarIndex )
	{
		//感觉这里没有必要使用IsExist属性
		if( !VarList.Get( VarIndex ).IsExist ) {
			return;
		}
		if( VarList.Get( VarIndex ).IsOut ) {
			return;
		}
		VarList.Get( VarIndex ).IsExist = false;
		string Type = VarList.Get( VarIndex ).Type;
		string VdataName = VarType.GetStoreType( Type );
		int VdataIndex = VdataList.GetIndex( VdataName );
		if( VdataIndex == -1 ) {
			ET.WriteParseError( 0, "在释放变量存储空间时发现未定义的虚拟数据类型:" + VdataName );
			return;
		}
		if( !VdataList.Get( VdataIndex ).AutoAllot ) {
			return;
		}
		int Width = VarType.GetSize( Type );
		string Address = VarList.GetAddr( VarIndex );
		if( Address == null ) {
			ET.WriteParseError( VarList.Get( VarIndex ).Location, "不能删除未分配地址的变量" );
			return;
		}
		int Addr = int.Parse( Address );
		if( Addr == -1 ) {
			ET.ShowError( "系统错误: 试图释放未分配地址的变量: " + VdataName + " " + Type + " " + VarIndex );
			return;
		}
		Addr -= VdataList.Get( VdataIndex ).StartAddress;
		for( int i = Addr; i < Addr + Width; ++i ) {
			if( AddressList.Address[ VdataIndex ][ i ] == false ) {
				ET.ShowError( "系统错误: 变量已经被释放: " + VdataIndex + " " + Addr );
			}
			AddressList.Address[ VdataIndex ][ i ] = false;
		}
	}
	
	//更新已用的最大静态变量地址
	public static void RefreshMaxStaticUsedAddress( int UnitIndex, int Addr )
	{
		if( StaticMaxAddr[ UnitIndex ] < Addr ) {
			StaticMaxAddr[ UnitIndex ] = Addr;
		}
	}
	
	//显示所有元件的分配地址长度
	public static string Show()
	{
		string Result = "";
		for( int idx = 0; idx < Number.Length; ++idx ) {
			Result += "第 " + idx + " 个元件类型分配的地址数目: " + Number[ idx ] + "\n";
		}
		return Result;
	}
	
	public static bool[][] Address;
	public static int[] Number;
	public static int[] StaticMaxAddr;
	public static int[][] MaxUsedAddressList;	//已用的最大地址
	public static string[][] UsedAddressList;	//已经使用的地址列表
}
}
